<!--
 * @Author       : wfl
 * @LastEditors: '张朋朋' '14065467+a598001989@user.noreply.gitee.com'
 * @description  :
 * @updateInfo   :
 * @Date         : 2023-10-31 11:13:02
 * @LastEditTime: 2024-04-18 18:00:20
-->
<template>
  <div>
    <!-- <div class="new-projects-title">选择下面的方式进行创建</div> -->
    <div class="project-template">
      <div class="title">
        <p>精选资源</p>
        <router-link :to="{ name: 'CreateScreen' }" target="_blank">
          更多精选资源
        </router-link>
      </div>
      <div class="template-list">
        <div
          v-for="(temp, index) in templatesList"
          :key="temp.id"
          class="template-item"
        >
          <img
            v-if="!temp.type"
            v-lazy="temp.isSystem ? sysLogo : publicLogo"
            class="temp-snap"
          >
          <img
            v-if="!temp.type"
            v-lazy="temp.snapshot"
            alt=""
            class="preview-image"
          >
          <div v-if="temp.type === 'more'" class="preview-image more-text">
            <router-link :to="{ name: 'CreateScreen' }" target="_blank">
              更多资源...
            </router-link>
          </div>
          <p class="template-name" :title="temp.name">{{ temp.name }}</p>

          <div v-if="!temp.type" class="template-mask">
            <n-button
              type="primary"
              :focusable="false"
              class="create-btn"
              @click="handCreateByTemplate(temp, index)"
            >
              创建
            </n-button>
          </div>
        </div>
        <div class="more-item">123</div>
      </div>
    </div>
    <div class="project-header">
      <div class="project-title">
        <h2>
          {{ group ? group.name : ""
          }}<span class="datav-tip-font">({{ page.total || "暂无" }})</span>
        </h2>
      </div>
      <div class="header-manager">
        <!-- <n-upload
          accept=".zip"
          :action="action"
          multiple
          :show-file-list="false"
          style="margin-right: 16px"
          @before-upload="beforeUpload"
          @finish="finishUpload"
        >
          <n-button secondary>导入</n-button>
        </n-upload>
        <n-button
          secondary
          :type="exportCheck ? 'warning' : 'info'"
          @click="handExportCheckScreen"
        >
          {{ exportCheck ? "取消导出" : "导出" }}
        </n-button>
        <n-button
          v-if="checkScreenLen && exportCheck"
          secondary
          type="primary"
          @click="createExport"
        >
          开始导出<span v-if="checkScreenLen">({{ checkScreenLen }})</span>
        </n-button>
        <n-button
          v-if="checkScreenLen && checking"
          secondary
          type="primary"
          @click="createRelease"
        >
          开始构建<span v-if="checkScreenLen">({{ checkScreenLen }})</span>
        </n-button>
        <n-button
          secondary
          :type="checking ? 'warning' : 'info'"
          @click="handCheckScreen"
        >
          {{ checking ? "取消构建" : "构建部署包" }}
        </n-button>
        <n-button type="info" secondary @click="handBuildList">
          构建记录
        </n-button> -->
        <div class="search-wrapper">
          <n-pagination
            :item-count="page.total"
            :page-sizes="[20, 30, 40, 50, 60]"
            show-quick-jumper
            show-size-picker
            :page-slot="8"
            :page="page.page"
            @update:page="handlePageChange"
            @update:page-size="handlePageSizeChange"
          />
          <div class="search">
            <input
              v-model.trim="searchText"
              clearable
              class="search-input"
              placeholder="搜索"
            >
          </div>
          <n-icon class="icon-search">
            <IconSearch @click="getProjectScreen" />
          </n-icon>

          <n-dropdown
            :options="sortOpts"
            :show-arrow="true"
            @select="handleSortChange"
          >
            <div class="sort-type">
              <span class="sort-text" :title="sorts[sort]">
                {{ sorts[sort] }}
              </span>
              <n-icon class="icon-arrow">
                <IconArrowDown />
              </n-icon>
            </div>
          </n-dropdown>
        </div>
      </div>
    </div>
    <n-spin :show="showLoading">
      <div class="main-screen">
        <div class="new-projects">
          <div class="create-new-project" @click="handCreateNew">
            <img src="@/assets/img/home/位图(1).webp">
            <span class="project-type ellipsis">创建空白项目</span>
          </div>
        </div>
        <n-checkbox-group v-model:value="checkScreens">
          <div
            v-for="screen in proScreens"
            :key="screen?.id"
            class="screen-item"
            :class="{ checked: checkScreens.includes(screen?.id) }"
          >
            <my-screen :screen="screen" />
            <n-checkbox
              v-if="checking || exportCheck"
              :value="screen?.id"
              label=""
            />
          </div>
        </n-checkbox-group>
      </div>
    </n-spin>
    <publish-screen v-model="visiblePublish" :screen-id="publishAppId" @publishSucceed="getProjectScreen" />
    <ScreenRelease
      v-model="showRelease"
      :project-id="group?.id"
      :screen="group"
    />
    <CreateEmptyScreen
      v-model="showNewScreen"
      :project-id="group?.id"
      @request="getProjectScreen"
    />
    <CreateTempScreen
      v-model="showTempScreen"
      :use-template="useTemplate"
      :project-id="group?.id"
      :templates="templatesList"
      @request="getProjectScreen"
    />
  </div>
</template>

<script lang='ts'>
import { defineComponent, PropType, provide, ref, watch } from 'vue'
import {
  NButton,
  NCheckbox,
  NCheckboxGroup,
  NPagination,
  NSpin,
  UploadFileInfo,
  useDialog,
  useMessage,
} from 'naive-ui'
import { ProjectGroup, ProjectTemplate } from '@/domains/project'
import { IconArrowDown, IconSearch } from '@/icons'
import MyScreen from './my-screen.vue'
import PublishScreen from './publish-screen.vue'
import { projectListInjectionKey } from './config'
import { getScreenPage } from '@/api/screen'
import { getSysTemplates } from '@/api/templates'
import sysLogo from '@/assets/img/home/sys.webp'
import publicLogo from '@/assets/img/home/public.webp'
import { exportScreens } from '@/api/project'
import ScreenRelease from './export-screen.vue'
import CreateEmptyScreen from './create-empty-screen.vue'
import CreateTempScreen from './create-temp-screen.vue'
export default defineComponent({
  name: 'ProjectList',
  components: {
    MyScreen,
    PublishScreen,
    IconSearch,
    IconArrowDown,
    NButton,
    NCheckboxGroup,
    NCheckbox,
    ScreenRelease,
    CreateEmptyScreen,
    CreateTempScreen,
    NSpin,
    NPagination,
  },
  props: {
    group: Object as PropType<ProjectGroup>,
  },
  setup(props) {
    const dialog = useDialog()
    const nMessage = useMessage()
    const searchText = ref('')
    const sort = ref('createTime')
    const sorts = {
      name: '按名称排序',
      createTime: '按创建时间排序',
      updateTime: '按修改时间排序',
    }
    const sortOpts = Object.entries(sorts).map(([key, label]) => ({
      key,
      label,
    }))
    const visiblePublish = ref(false)
    const publishAppId = ref('')

    const handleSortChange = (key: string) => {
      sort.value = key
      getProjectScreen()
    }

    const proScreens = ref([])
    const showLoading = ref(false)
    const page = ref({
      page: 1,
      rows: 20,
      total: 0,
    })
    const getProjectScreen = async () => {
      try {
        const res = await getScreenPage({
          page: page.value.page,
          rows: page.value.rows,
          groupId: props.group?.id,
          name: searchText.value,
          order: sort.value,
        })
        showLoading.value = true
        if (res.success) {
          proScreens.value = []
          setTimeout(() => {
            proScreens.value = res.data
            page.value.total = res.total || 0
          })
        } else {
          nMessage.error(res.msg)
          page.value.total = 0
          proScreens.value = []
        }
      } catch (error) {
        showLoading.value = false
      }
      showLoading.value = false
    }
    watch(
      () => props.group,
      val => {
        if (val) {
          page.value.page = 1
          getProjectScreen()
        }
      },
      { deep: true },
    )

    provide(projectListInjectionKey, {
      publish(appId: number | string) {
        visiblePublish.value = true
        publishAppId.value = appId as any
      },
    })

    const templatesList = ref([])
    const { setUrl } = useEnvUrl()
    const showLength = ref(0)
    const getSystemTemplate = async () => {
      const res = await getSysTemplates()
      if (res.success)
        templatesList.value = res.data?.map(v => {
          return {
            ...v,
            snapshot: setUrl(v.snapshot),
          }
        })
      else {
        templatesList.value = []
      }
      checkOverflow()
    }
    getSystemTemplate()

    // ========导入======
    const action = import.meta.env.VITE_UPLOAD_URL
    const beforeUpload = async (options: { file: UploadFileInfo; }) => {}
    const finishUpload = (options: {
      file: UploadFileInfo
      event?: ProgressEvent
    }) => {}

    // ========导出======
    const exportCheck = ref(false)
    const handExportCheckScreen = () => {
      exportCheck.value = !exportCheck.value
      !exportCheck.value && (checkScreens.value = [])
    }

    const createExport = () => {
      dialog.warning({
        title: '提示',
        content: '你确定导出已选数据吗？',
        positiveText: '确定',
        negativeText: '取消',
        showIcon: false,
        onPositiveClick: async () => {
          const res = await exportScreens({
            projectId: props.group?.id,
            id: checkScreens.value,
          })
          if (res.success) {
            nMessage.success('正在导出，请1分钟后查看下载...')
            handExportCheckScreen()
          }
        },
        onNegativeClick: async () => {
          handExportCheckScreen()
        },
      })
    }
    // UN_PUBLISH ======================= 构建部署包 ===================================
    const checking = ref(false)
    const checkScreens = ref([])
    const checkScreenLen = computed(() => checkScreens.value.length)
    // 选择需要构建的应用
    const handCheckScreen = () => {
      checking.value = !checking.value
      !checking.value && (checkScreens.value = [])
    }

    const createRelease = () => {
      dialog.warning({
        title: '提示',
        content: '你确定构建已选数据吗？',
        positiveText: '确定',
        negativeText: '取消',
        showIcon: false,
        onPositiveClick: async () => {
          const res = await exportScreens({
            projectId: props.group?.id,
            id: checkScreens.value,
          })
          if (res.success) {
            nMessage.success('正在打包，请1分钟后查看下载...')
            handCheckScreen()
          }
        },
        onNegativeClick: async () => {
          handCheckScreen()
        },
      })
    }
    const showRelease = ref(false)
    const handBuildList = () => {
      showRelease.value = true
    }

    //======================= 新建空白应用 ===================================
    const showNewScreen = ref(false)
    const handCreateNew = () => {
      showNewScreen.value = true
    }

    const useTemplate = ref()
    const showTempScreen = ref(false)
    const handCreateByTemplate = (tpl: ProjectTemplate, idx: number) => {
      showTempScreen.value = true
      useTemplate.value = tpl
    }

    const handlePageSizeChange = (size: number) => {
      page.value.rows = size
      getProjectScreen()
    }
    const handlePageChange = (cur_page: number) => {
      page.value.page = cur_page
      getProjectScreen()
    }

    const checkOverflow = () => {
      const container = document.querySelector('.template-list')
      const width = window.getComputedStyle(container).width.slice(0, -2)
      // 元素宽度160+间距14   间距个数为列-1   所以 174不合适
      showLength.value = Math.floor((width * 1) / 165)
      if (templatesList.value.length > showLength.value) {
        templatesList.value.splice(showLength.value - 1, 0, {
          type: 'more',
        })
      }
    }

    return {
      searchText,
      sort,
      sorts,
      sortOpts,
      visiblePublish,
      publishAppId,
      proScreens,
      templatesList,
      sysLogo,
      publicLogo,
      exportCheck,
      checking,
      checkScreens,
      showRelease,
      checkScreenLen,
      showNewScreen,
      showTempScreen,
      useTemplate,
      showLoading,
      page,
      handCreateByTemplate,
      handlePageSizeChange,
      handlePageChange,
      handleSortChange,
      handCheckScreen,
      createRelease,
      handBuildList,
      handCreateNew,
      getProjectScreen,
      createExport,
      handExportCheckScreen,
      action,
      beforeUpload,
      finishUpload,
    }
  },
})
</script>

<style lang="scss" scoped>
@import "./project-list.scss";
</style>
